package br.com.conciliador.upload.apresentacao;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;

import br.com.conciliador.cadastro.negocio.BandeiraNgc;
import br.com.conciliador.cadastro.negocio.EstLojaNgc;
import br.com.conciliador.cadastro.negocio.ProdutoNgc;
import br.com.conciliador.cadastro.vo.BandeiraVo;
import br.com.conciliador.cadastro.vo.EstLojaVo;
import br.com.conciliador.cadastro.vo.ProdutoVo;
import br.com.conciliador.seguranca.vo.ExtensaoUsuarioVo;
import br.com.conciliador.seguranca.vo.UsuarioVo;
import br.com.conciliador.upload.negocio.HeaderArquivoRemessaVendasNgc;
import br.com.conciliador.upload.vo.DetalheArquivoRemessaVendasVo;
import br.com.conciliador.upload.vo.HeaderArquivoRemessaVendasVo;
import br.com.conciliador.upload.vo.filtro.FiltroHeaderArquivoRemessaVendasVo;
import br.com.conciliador.util.Colecao;
import br.com.conciliador.util.jsf.AbstractBean;
import br.com.conciliador.util.jsf.JSFUtil;
import br.com.r2.exception.R2Exception;
import br.com.r2.util.tipodado.Data;
import br.com.r2.util.tipodado.Flag;
import br.com.r2.util.tipodado.Inteiro;
import br.com.r2.util.tipodado.Moeda;
import br.com.r2.util.tipodado.Texto;
import br.com.r2.util.tipodado.YesNo;

public class HeaderArquivoRemessaVendasBean extends AbstractBean<HeaderArquivoRemessaVendasVo, HeaderArquivoRemessaVendasNgc>
{

   private List<EstLojaVo> listaEstLojas;

   private List<BandeiraVo> listaBandeiras;

   private List<ProdutoVo> listaProdutos;

   private Inteiro qtdeTotal;

   private Moeda valorTotal;
   
   private boolean exibirListaLojas;
   
   JSFUtil util = new JSFUtil();
   
   private List<DetalheArquivoRemessaVendasVo> listaDetalhes;
   
   public HeaderArquivoRemessaVendasBean()
   {
      super(HeaderArquivoRemessaVendasNgc.getInstancia());
      this.ACTION_SEARCH = "headerArquivoRemessaVendas";
      this.pageTitle = "titulo_arquivo_remessa_vendas";
   }

   
   @Override
   protected void setListaPesquisa() throws R2Exception
   {
      setarListaEstLojas();
      setarListaBandeiras();
   }

   @Override
   public String preparaPesquisar()
   {

      String retorno = super.preparaPesquisar();
      if (this.getSearchObject().getFiltro() == null)
      {
    	  this.getSearchObject().setFiltro(new FiltroHeaderArquivoRemessaVendasVo());
      }
      
      Data filtroData = new Data(new Date());
      this.getSearchObject().getFiltro().setDataImportacaoFinal(filtroData);
      filtroData = new Data(new Date());
      filtroData.add(GregorianCalendar.DAY_OF_MONTH, -1);
      this.getSearchObject().getFiltro().setDataImportacaoInicial(filtroData);
      
      try
      {
         this.getSearchObject().getFiltro().setUsuarioVo(util.getUsuarioLogado());
      }
      catch (R2Exception e)
      {
         e.printStackTrace();
      }

      return retorno;
   }
   
   @Override
   protected void validarPesquisar() throws R2Exception
   {
      if (this.getSearchObject().getFiltro() == null)
      {
         throw new R2Exception("peloMenosUmDosCamposObrigatorios");
      }
      
      boolean dataGeracao = this.getSearchObject().getFiltro().getDataGeracaoInicial() == null || !this.getSearchObject().getFiltro().getDataGeracaoInicial().isPreenchido();  
      boolean dataImportacao = this.getSearchObject().getFiltro().getDataImportacaoInicial() == null || !this.getSearchObject().getFiltro().getDataImportacaoInicial().isPreenchido();  
      boolean dataVenda = this.getSearchObject().getFiltro().getDataVendaInicial() == null || !this.getSearchObject().getFiltro().getDataVendaInicial().isPreenchido();  

      if (dataGeracao && dataImportacao && dataVenda)
      {
         throw new R2Exception("peloMenosUmDosCamposObrigatorios");
      }
   }

   private void setarListaEstLojas() throws R2Exception
   {
	      UsuarioVo usuarioVo = util.getUsuarioVo();
	      this.setExibirListaLojas(true);

	      if (usuarioVo == null)
	      {
	         throw new R2Exception("usuario.logado.nao.sessao");
	      }

	      if (usuarioVo.getEstEmpresaVo() == null || usuarioVo.getEstEmpresaVo().getCodigo() == null || !usuarioVo.getEstEmpresaVo().getCodigo().isPreenchido())
	      {
	         throw new R2Exception("usuario.logado.sem.empresa");
	      }

	      this.listaEstLojas = new ArrayList<EstLojaVo>();
	      
	      if (usuarioVo.getListaExtensaoUsuarioVo() == null || usuarioVo.getListaExtensaoUsuarioVo().size() == 0)
	      {
	         EstLojaVo estLojaVo = new EstLojaVo();
	         estLojaVo.setEstEmpresaVo(usuarioVo.getEstEmpresaVo());
	         estLojaVo.setSituacao(new Flag(YesNo.YES));
	         
	         List<EstLojaVo> lista = EstLojaNgc.getInstancia().pesquisar(estLojaVo, EstLojaNgc.JOIN_EST_EMPRESA);

	         EstLojaVo vazio = new EstLojaVo();
	         vazio.setDescricao(new Texto("TODAS"));

	         this.listaEstLojas.add(vazio);
	         this.listaEstLojas.addAll(lista);
	      }
	      else if (usuarioVo.getListaExtensaoUsuarioVo().size() > 1)
	      {
	         EstLojaVo vazio = new EstLojaVo();
	         vazio.setDescricao(new Texto("TODAS"));
	         this.listaEstLojas.add(vazio);
	         
	         List<EstLojaVo> lista = new ArrayList<EstLojaVo>();
	         Iterator<ExtensaoUsuarioVo> iterator = usuarioVo.getListaExtensaoUsuarioVo().iterator();
	         while (iterator.hasNext())
	         {
	            ExtensaoUsuarioVo element = (ExtensaoUsuarioVo) iterator.next();
	            lista.add(element.getEstLojaVo());
	         }
	         
	         Collections.sort(lista, new Comparator()
	         {
	            public int compare(Object o1, Object o2)
	            {
	               String c1 = ((EstLojaVo) o1).getDescricao().getValor();
	               String c2 = ((EstLojaVo) o2).getDescricao().getValor();
	               return c1.compareTo(c2);
	            }
	         }
	         );
	         
	         this.listaEstLojas.addAll(lista);
	      }
	      else
	      {
	         List<ExtensaoUsuarioVo> lista = new ArrayList<ExtensaoUsuarioVo>(usuarioVo.getListaExtensaoUsuarioVo());
	         ExtensaoUsuarioVo extensaoUsuarioVo = (ExtensaoUsuarioVo) lista.get(0);
	         if (this.getSearchObject().getFiltro() == null)
	         {
	            this.getSearchObject().setFiltro(new FiltroHeaderArquivoRemessaVendasVo());
	         }
	         this.getSearchObject().getFiltro().setEstLoja(extensaoUsuarioVo.getEstLojaVo().getCodigo());
	         this.getSearchObject().getFiltro().setNomeEstLoja(extensaoUsuarioVo.getEstLojaVo().getDescricao());
	         this.setExibirListaLojas(false);
	      }
   }

   private void setarListaBandeiras() throws R2Exception
   {
      this.listaBandeiras = new ArrayList<BandeiraVo>();
      BandeiraVo bandeiraVo = new BandeiraVo();
      List<BandeiraVo> lista = BandeiraNgc.getInstancia().pesquisar(bandeiraVo,0);

      BandeiraVo vazio = new BandeiraVo();
      vazio.setDescricao(new Texto("TODAS"));

      this.listaBandeiras.add(vazio);
      this.listaBandeiras.addAll(lista);
   }
   
   public void setarListaProdutos(ActionEvent event) throws R2Exception
   {
      if (this.getSearchObject().getFiltro().getBandeira() != null && this.getSearchObject().getFiltro().getBandeira().isPreenchido())
      {
         ProdutoVo produtoVo = new ProdutoVo();
         BandeiraVo bandeiraVo = new BandeiraVo();
         bandeiraVo.setCodigo(this.getSearchObject().getFiltro().getBandeira());
         produtoVo.setBandeiraVo(bandeiraVo);
         int join = ProdutoNgc.JOIN_BANDEIRA;
         List<ProdutoVo> lista = ProdutoNgc.getInstancia().pesquisar(produtoVo, join);
         
         produtoVo = new ProdutoVo();
         produtoVo.setDescricao(new Texto("TODOS"));
         this.setListaProdutos(new ArrayList<ProdutoVo>());
         this.getListaProdutos().add(produtoVo);
         if (lista != null)
         {
            this.getListaProdutos().addAll(lista);
         }
      }
   }

   @Override
   protected int getJoinPesquisar()
   {
      int join = HeaderArquivoRemessaVendasNgc.JOIN_DETALHE
                 | HeaderArquivoRemessaVendasNgc.JOIN_DETALHE_BANDEIRA
                 | HeaderArquivoRemessaVendasNgc.JOIN_DETALHE_DATA_VENDA
                 | HeaderArquivoRemessaVendasNgc.JOIN_DETALHE_LOJA
                 | HeaderArquivoRemessaVendasNgc.JOIN_DETALHE_PRODUTO
                 | HeaderArquivoRemessaVendasNgc.JOIN_USUARIO_RECEBIMENTO
                 | HeaderArquivoRemessaVendasNgc.JOIN_EMPRESA;
      return join;
   }

   @Override
   public void pesquisar(ActionEvent event)
   {
      try
      {
         validarPesquisar();
         UsuarioVo usuarioVo = util.getUsuarioVo();
         if (usuarioVo == null)
         {
            throw new R2Exception("usuario.logado.nao.sessao");
         }
         if (usuarioVo.getEstEmpresaVo() == null
             || usuarioVo.getEstEmpresaVo().getCodigo() == null
             || !usuarioVo.getEstEmpresaVo().getCodigo().isPreenchido())
         {
            throw new R2Exception("usuario.logado.sem.empresa");
         }
         this.getSearchObject().getFiltro().setCodigoEmpresa(usuarioVo.getEstEmpresaVo().getCodigo());
         
         List<HeaderArquivoRemessaVendasVo> listaResultado = this.getBusiness().pesquisarResultTransformed(this.getSearchObject(), this.getJoinPesquisar());
         this.setSearchResult(listaResultado);
         
         double qtdeReg = Colecao.somaCampo(this.getSearchResult(), "QuantidadeRegistros");
         double valorReg = Colecao.somaCampo(this.getSearchResult(), "ValorRegistros");

         qtdeTotal = new Inteiro((int)qtdeReg);
         valorTotal = new Moeda(valorReg);
      }
      catch (R2Exception e)
      {
         FacesMessage message = new FacesMessage(e.getMensagem());  
         message.setSeverity(FacesMessage.SEVERITY_ERROR);  
         FacesContext.getCurrentInstance().addMessage("", message);
      }
   }
   
   @Override
   public void exibirSelecionado(ActionEvent event)
   {
      //super.exibirSelecionado(event);
      try
      {
         if (this.getSelectedRowEntity() != null)
         {

            HeaderArquivoRemessaVendasVo vo = this.getSelectedRowEntity();
            HeaderArquivoRemessaVendasVo filtroVo = new HeaderArquivoRemessaVendasVo();
            filtroVo.setCodigo(vo.getCodigo());
            HeaderArquivoRemessaVendasVo retornoVo = HeaderArquivoRemessaVendasNgc.getInstancia().visualizar(filtroVo, getJoinPesquisar());

            if (retornoVo != null)
            {
               this.setEntity(retornoVo);
               Set<DetalheArquivoRemessaVendasVo> set = this.getEntity().getListaDetalheArquivoRemessaVendasVo();
               this.listaDetalhes = new ArrayList<DetalheArquivoRemessaVendasVo>();
               this.listaDetalhes.addAll(set);
            }
            else
            {
               this.setEntity(this.getSelectedRowEntity());
            }

            setCurrentState(STATE_VIEW);
         }
      }
      catch (R2Exception e)
      {
         FacesMessage message = new FacesMessage(e.getMensagem());  
         message.setSeverity(FacesMessage.SEVERITY_ERROR);  
         FacesContext.getCurrentInstance().addMessage("", message);
      }
   }
   
   public List<EstLojaVo> getListaEstLojas()
   {
      return listaEstLojas;
   }

   public void setListaEstLojas(List<EstLojaVo> listaEstLojas)
   {
      this.listaEstLojas = listaEstLojas;
   }

   public List<BandeiraVo> getListaBandeiras()
   {
      return listaBandeiras;
   }

   public void setListaBandeiras(List<BandeiraVo> listaBandeiras)
   {
      this.listaBandeiras = listaBandeiras;
   }

   public List<ProdutoVo> getListaProdutos()
   {
      return listaProdutos;
   }

   public void setListaProdutos(List<ProdutoVo> listaProdutos)
   {
      this.listaProdutos = listaProdutos;
   }


   public Inteiro getQtdeTotal()
   {
      return qtdeTotal;
   }


   public void setQtdeTotal(Inteiro qtdeTotal)
   {
      this.qtdeTotal = qtdeTotal;
   }

   public Moeda getValorTotal()
   {
      return valorTotal;
   }

   public void setValorTotal(Moeda valorTotal)
   {
      this.valorTotal = valorTotal;
   }

   public List<DetalheArquivoRemessaVendasVo> getListaDetalhes()
   {
      return listaDetalhes;
   }

   public void setListaDetalhes(List<DetalheArquivoRemessaVendasVo> listaDetalhes)
   {
      this.listaDetalhes = listaDetalhes;
   }

   public boolean isExibirListaLojas()
   {
      return exibirListaLojas;
   }

   public void setExibirListaLojas(boolean exibirListaLojas)
   {
      this.exibirListaLojas = exibirListaLojas;
   }
}
